package ua.sumdu.LukyanovChalyi.Utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import ua.sumdu.LukyanovChalyi.Server.*;

public class XMLUtils {

    public static final String PAGES = "pages";
    public static final String DATE = "date";
    public static final String TITLE = "title";
    public static final String AUTHOR = "author";
    public static final String BOOK = "book";
    public static final String ACTIVE = "Active";
    public static final String ID = "id";
    public static final String COPY_BOOK = "copyBook";
    public static final String LIBRARY = "library";

    public Element makeCopyBook(Document doc, CopyBook cb) {
        Element copyBook = doc.createElement(COPY_BOOK);
        Book b = cb.getBook();
        Element invNumber = doc.createElement(ID);
        Element onHand = doc.createElement(ACTIVE);

        invNumber.appendChild(doc.createTextNode(String.valueOf(cb.getID())));
        onHand.appendChild(doc.createTextNode(String.valueOf(cb.isActive())));

        Element book = doc.createElement(BOOK);
        Element[] authors = new Element[b.getAuthors().size()];
        int count = 0;
        for (String auth : b.getAuthors()) {
            authors[count] = doc.createElement(AUTHOR);
            authors[count].appendChild(doc.createTextNode(auth));
            book.appendChild(authors[count]);
            count++;
        }

        Element title = doc.createElement(TITLE);
        Element imprintDate = doc.createElement(DATE);
        Element numberOfPages = doc.createElement(PAGES);

        title.appendChild(doc.createTextNode(b.getTitle()));
        imprintDate.appendChild((doc.createTextNode(String.valueOf(b.getDate()))));
        numberOfPages.appendChild(doc.createTextNode(String.valueOf(b.getNumberOfPages())));

        book.appendChild(title);
        book.appendChild(imprintDate);
        book.appendChild(numberOfPages);
        copyBook.appendChild(invNumber);

        copyBook.appendChild(onHand);
        copyBook.appendChild(book);
        return copyBook;
    }

    public CopyBook readCopyBook(Element copyBook) {

        long invNumber = Long.parseLong(copyBook.getElementsByTagName(ID).item(0).getFirstChild().getNodeValue());
        boolean onHand = Boolean.parseBoolean(copyBook.getElementsByTagName(ACTIVE).item(0).getFirstChild().getNodeValue());

        Element thisBook = (Element) copyBook.getElementsByTagName(BOOK).item(0);
        NodeList auth = thisBook.getElementsByTagName(AUTHOR);
        List<String> authors = new ArrayList<String>();

        for (int j = 0; j < auth.getLength(); j++) {
            Element thisAuthor = (Element) auth.item(j);
            authors.add(thisAuthor.getFirstChild().getNodeValue());
        }

        String title = thisBook.getElementsByTagName(TITLE).item(0).getFirstChild().getNodeValue();
        int date = Integer.parseInt(thisBook.getElementsByTagName(DATE).item(0).getFirstChild().getNodeValue());
        int pages = Integer.parseInt(thisBook.getElementsByTagName(PAGES).item(0).getFirstChild().getNodeValue());

        Book book = new Book(authors, title, date, pages);
        return new CopyBook(book, invNumber, onHand);
    }

    public Document getDocument(InputStream channel)
            throws ParserConfigurationException, IOException, SAXException {

        DocumentBuilderFactory docBuilderFact = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBuilderFact.newDocumentBuilder();
        Document request = null;
        XMLInputStream xmlin = new XMLInputStream(channel);
        xmlin.recive();
        request = docBuilder.parse(xmlin);
        return request;
    }

    public void writeDocumentToStream(Document tosend, OutputStream channel) throws TransformerConfigurationException, TransformerException, IOException {
        XMLOutputStream out = new XMLOutputStream(channel);
        StreamResult sr = new StreamResult(out);
        DOMSource ds = new DOMSource(tosend);
        Transformer tf = TransformerFactory.newInstance().newTransformer();
        tf.transform(ds, sr);
        out.send();
    }
}
